import { _decorator, Component, Node, Graphics, Vec2, Color, EventTouch, UITransform, Button, instantiate, Sprite, Prefab } from 'cc';
import { BezierMover } from './BezierMover';
const { ccclass, property } = _decorator;

interface CurvePoint {
    node: Node;
    type: 'start' | 'control' | 'end';
}

interface BezierCurve {
    startPoint: Vec2;
    controlPoint: Vec2;
    endPoint: Vec2;
    points: CurvePoint[];
}

interface BezierCurveData {
    startPoint: { x: number; y: number };
    controlPoint: { x: number; y: number };
    endPoint: { x: number; y: number };
}

interface ExportData {
    curves: BezierCurveData[];
    totalLength: number;
}

@ccclass('DrawLine')
export class DrawLine extends Component {
    @property(Graphics)
    private graphics: Graphics = null!;

    @property(Node)
    private addButton: Node = null!;

    @property(Node)
    private deleteButton: Node = null!;

    @property(Node)
    private pointTemplate: Node = null!;

    @property
    private lineWidth: number = 5;

    @property(Color)
    private lineColor: Color = new Color(255, 0, 0, 255);

    @property(Node)
    private exportButton: Node = null!;

    @property(Prefab)
    private moverPrefab: Prefab = null!;

    private curves: BezierCurve[] = [];
    private currentDraggingPoint: CurvePoint | null = null;
    private isCreatingCurve: boolean = false;
    private activeMover: Node | null = null;

    start() {
        if (!this.graphics) {
            this.graphics = this.getComponent(Graphics);
            if (!this.graphics) {
                this.graphics = this.addComponent(Graphics);
            }
        }

        // 初始化按钮事件
        this.initializeButtons();
    }

    private initializeButtons() {
        const addBtn = this.addButton.getComponent(Button);
        const deleteBtn = this.deleteButton.getComponent(Button);
        const exportBtn = this.exportButton.getComponent(Button);

        addBtn?.node.on(Button.EventType.CLICK, this.onAddCurveClick, this);
        deleteBtn?.node.on(Button.EventType.CLICK, this.onDeleteCurveClick, this);
        exportBtn?.node.on(Button.EventType.CLICK, this.onExportClick, this);
    }

    /**
     * 获取屏幕视图大小
     */
    private getViewBounds(): { width: number; height: number } {
        const canvas = this.node.parent;
        if (canvas) {
            const uiTransform = canvas.getComponent(UITransform);
            if (uiTransform) {
                return {
                    width: uiTransform.width,
                    height: uiTransform.height
                };
            }
        }
        // 默认值
        return { width: 960, height: 640 };
    }

    /**
     * 确保点在视图范围内
     */
    private clampPointToView(point: Vec2, startPoint: Vec2, maxDistance: number): Vec2 {
        const viewBounds = this.getViewBounds();
        const halfWidth = viewBounds.width / 2;
        const halfHeight = viewBounds.height / 2;

        // 首先限制在屏幕范围内
        let x = Math.max(-halfWidth, Math.min(halfWidth, point.x));
        let y = Math.max(-halfHeight, Math.min(halfHeight, point.y));

        // 然后限制与起点的距离
        const direction = new Vec2(x - startPoint.x, y - startPoint.y);
        const currentDistance = direction.length();
        if (currentDistance > maxDistance) {
            direction.multiplyScalar(maxDistance / currentDistance);
            x = startPoint.x + direction.x;
            y = startPoint.y + direction.y;
        }

        return new Vec2(x, y);
    }

    private onAddCurveClick() {
        if (this.isCreatingCurve) return;
        this.isCreatingCurve = true;

        const points: CurvePoint[] = [];
        const types: ('start' | 'control' | 'end')[] = ['start', 'control', 'end'];

        // 获取起始位置
        let startPos: Vec2;
        if (this.curves.length > 0) {
            const lastCurve = this.curves[this.curves.length - 1];
            startPos = lastCurve.endPoint.clone();
        } else {
            startPos = new Vec2(-100, -100);
        }

        // 设置最大距离
        const MAX_CONTROL_DISTANCE = 100;  // 控制点最大距离
        const MAX_END_DISTANCE = 200;      // 终点最大距离

        // 计算控制点和终点的理想位置
        const idealControlPos = new Vec2(
            startPos.x + 50,
            startPos.y + 50
        );

        const idealEndPos = new Vec2(
            startPos.x + 100,
            startPos.y
        );

        // 限制控制点和终点的位置
        const controlPos = this.clampPointToView(idealControlPos, startPos, MAX_CONTROL_DISTANCE);
        const endPos = this.clampPointToView(idealEndPos, startPos, MAX_END_DISTANCE);

        // 创建三个点
        for (let i = 0; i < 3; i++) {
            const point = this.createDraggablePoint(types[i]);
            points.push(point);
        }

        // 设置点的位置
        points[0].node.setPosition(startPos.x, startPos.y);
        points[1].node.setPosition(controlPos.x, controlPos.y);
        points[2].node.setPosition(endPos.x, endPos.y);

        // 创建新的曲线对象
        const curve: BezierCurve = {
            startPoint: startPos,
            controlPoint: controlPos,
            endPoint: endPos,
            points: points
        };

        this.curves.push(curve);
        this.updateAllCurves();
        this.isCreatingCurve = false;
    }

    private onDeleteCurveClick() {
        if (this.curves.length === 0) return;

        const lastCurve = this.curves.pop();
        if (lastCurve) {
            // 删除控制点节点
            lastCurve.points.forEach(point => {
                point.node.destroy();
            });
            this.updateAllCurves();
        }
    }

    private createDraggablePoint(type: 'start' | 'control' | 'end'): CurvePoint {
        const node = instantiate(this.pointTemplate);
        node.parent = this.node;
        node.active = true;

        const color = type === 'control' ? Color.BLUE : Color.GREEN;
        const sprite = node.getComponent(Sprite);
        if (sprite) {
            sprite.color = color;
        }

        node.on(Node.EventType.TOUCH_START, (event: EventTouch) => {
            this.currentDraggingPoint = { node, type };
        });

        node.on(Node.EventType.TOUCH_MOVE, (event: EventTouch) => {
            if (this.currentDraggingPoint && this.currentDraggingPoint.node === node) {
                const delta = event.getDelta();
                const pos = node.getPosition();
                const newPos = new Vec2(pos.x + delta.x, pos.y + delta.y);

                // 获取当前曲线的起点
                const curve = this.curves.find(c => c.points.includes(this.currentDraggingPoint!));
                if (curve) {
                    const maxDistance = type === 'control' ? 100 : 200;
                    const clampedPos = this.clampPointToView(newPos, curve.startPoint, maxDistance);
                    node.setPosition(clampedPos.x, clampedPos.y);
                } else {
                    node.setPosition(newPos.x, newPos.y);
                }

                this.updateCurveFromPoints();
            }
        });

        node.on(Node.EventType.TOUCH_END, () => {
            this.currentDraggingPoint = null;
        });

        node.on(Node.EventType.TOUCH_CANCEL, () => {
            this.currentDraggingPoint = null;
        });

        return { node, type };
    }

    private updateCurveFromPoints() {
        this.curves.forEach(curve => {
            curve.points.forEach(point => {
                const pos = point.node.getPosition();
                const vec2Pos = new Vec2(pos.x, pos.y);

                switch (point.type) {
                    case 'start':
                        curve.startPoint = vec2Pos;
                        break;
                    case 'control':
                        curve.controlPoint = vec2Pos;
                        break;
                    case 'end':
                        curve.endPoint = vec2Pos;
                        break;
                }
            });
        });

        this.updateAllCurves();
    }

    private updateAllCurves() {
        this.graphics.clear();

        this.curves.forEach(curve => {
            this.drawSingleBezierCurve(
                curve.startPoint,
                curve.controlPoint,
                curve.endPoint
            );
        });
    }

    /**
     * 绘制单条贝塞尔曲线
     */
    private drawSingleBezierCurve(
        startPoint: Vec2,
        controlPoint: Vec2,
        endPoint: Vec2
    ) {
        // 设置线条属性
        this.graphics.lineWidth = this.lineWidth;
        this.graphics.strokeColor = this.lineColor;

        // 开始绘制
        this.graphics.moveTo(startPoint.x, startPoint.y);
        this.graphics.quadraticCurveTo(
            controlPoint.x, controlPoint.y,
            endPoint.x, endPoint.y
        );

        // 应用描边
        this.graphics.stroke();

        // 绘制辅助线
        this.graphics.strokeColor = new Color(100, 100, 100, 100);
        this.graphics.lineWidth = 1;
        this.graphics.moveTo(startPoint.x, startPoint.y);
        this.graphics.lineTo(controlPoint.x, controlPoint.y);
        this.graphics.lineTo(endPoint.x, endPoint.y);
        this.graphics.stroke();

        // 计算并显示长度
        const length = this.calculateBezierLength(startPoint, controlPoint, endPoint);
        // console.log(`Curve length: ${length.toFixed(2)} units`);
    }

    /**
     * 计算贝塞尔曲线长度
     */
    public calculateBezierLength(
        startPoint: Vec2,
        controlPoint: Vec2,
        endPoint: Vec2,
        segments: number = 100
    ): number {
        let length = 0;
        let lastPoint = this.getPointOnCurve(startPoint, controlPoint, endPoint, 0);

        for (let i = 1; i <= segments; i++) {
            const t = i / segments;
            const currentPoint = this.getPointOnCurve(startPoint, controlPoint, endPoint, t);
            length += Vec2.distance(lastPoint, currentPoint);
            lastPoint = currentPoint;
        }

        return length;
    }

    /**
     * 获取曲线上某一点的位置
     */
    private getPointOnCurve(
        startPoint: Vec2,
        controlPoint: Vec2,
        endPoint: Vec2,
        t: number
    ): Vec2 {
        const t1 = 1 - t;
        const t1Squared = t1 * t1;
        const tSquared = t * t;

        const x = t1Squared * startPoint.x +
            2 * t1 * t * controlPoint.x +
            tSquared * endPoint.x;

        const y = t1Squared * startPoint.y +
            2 * t1 * t * controlPoint.y +
            tSquared * endPoint.y;

        return new Vec2(x, y);
    }

    /**
     * 导出贝塞尔曲线数据并创建移动物体
     */
    private onExportClick() {
        console.log('Exporting Bezier Curves Data...');
        const exportData = this.exportCurveData();
        // console.log('Exported Bezier Curves Data:', JSON.stringify(exportData, null, 2));

        // 如果已经有移动物体，先销毁它
        if (this.activeMover) {
            this.activeMover.destroy();
            this.activeMover = null;
        }

        // 创建新的移动物体
        this.createMover(exportData);
    }

    /**
     * 创建移动物体
     */
    private createMover(data: ExportData) {
        if (!this.moverPrefab) {
            // console.error('Mover prefab is not set!');
            return;
        }
        this.saveToCLipboard(data);
        // 创建移动物体
        const moverNode = instantiate(this.moverPrefab);
        moverNode.parent = this.node;
        this.activeMover = moverNode;

        // 获取并设置BezierMover组件
        const mover = moverNode.getComponent(BezierMover);
        if (mover) {
            // 可以在这里设置初始索引，或者使用组件上配置的值
            // mover.initialIndex = 30; // 如果需要在代码中设置
            mover.setBezierData(data);
            mover.startMove();
        }
    }

    /**
     * 导出曲线数据
     */
    private exportCurveData(): ExportData {
        let totalLength = 0;
        const curvesData: BezierCurveData[] = this.curves.map(curve => {
            const length = this.calculateBezierLength(
                curve.startPoint,
                curve.controlPoint,
                curve.endPoint
            );
            totalLength += length;

            return {
                startPoint: { x: curve.startPoint.x, y: curve.startPoint.y },
                controlPoint: { x: curve.controlPoint.x, y: curve.controlPoint.y },
                endPoint: { x: curve.endPoint.x, y: curve.endPoint.y }
            };
        });

        return {
            curves: curvesData,
            totalLength: totalLength
        };
    }

    /**
     * 将数据保存到剪贴板
     */
    private saveToCLipboard(data: ExportData) {
        const jsonString = JSON.stringify(data, null, 2);

        // 创建一个临时textarea元素
        const textarea = document.createElement('textarea');
        textarea.value = jsonString;
        document.body.appendChild(textarea);

        // 选择文本并复制
        textarea.select();
        try {
            document.execCommand('copy');
            console.log('数据已复制到剪贴板');
        } catch (err) {
            console.error('复制到剪贴板失败:', err);
        }

        // 移除临时元素
        document.body.removeChild(textarea);
    }

    // 添加一个方法来控制当前移动物体的位置
    public setMoverPosition(index: number) {
        if (this.activeMover) {
            const mover = this.activeMover.getComponent(BezierMover);
            if (mover) {
                mover.moveIndex = index;
                // 或者使用
                // mover.jumpToIndex(index);
            }
        }
    }

    // 添加一个方法来获取当前位置
    public getMoverPosition(): number {
        if (this.activeMover) {
            const mover = this.activeMover.getComponent(BezierMover);
            if (mover) {
                return mover.moveIndex;
            }
        }
        return 0;
    }
}


